package com.ygqh.baby.handler;

import com.alibaba.fastjson.JSON;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.model.OrderDetailReturnData;
import com.ygqh.baby.model.ReturnSkuInfo;
import com.ygqh.baby.model.YgReturnInfoModel;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.DateConvertUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 〈〉
 *
 * @author guohao
 * @date 2019/5/16 12:27
 * @since 1.0.0
 */
@Component
public class SaveReturnOrderHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private YgSkuService ygSkuService;
    @Autowired
    private YgOrderService ygOrderService;
    @Autowired
    private YgReturnOrderDetailService ygReturnOrderDetailService;
    @Autowired
    private YgReturnOrderService ygReturnOrderService;
    @Autowired
    private YgFrameCodeService ygFrameCodeService;
    @Autowired
    private YgReturnOrderLogService ygReturnOrderLogService;
    @Autowired
    private YgPrepayBookRecordService ygPrepayBookRecordService;

    public Message saveReturnOffOrder(YgReturnInfoModel infoModel, ReturnReasonType returnReasonType, String returnReason,
                                      String imgPaths, Long userId, String trueName) {
        logger.info("saveReturnOffOrder param : infoModel = 【{}】", JSON.toJSONString(infoModel));


        YgOrder order = ygOrderService.findOrderDetailByOrderId(infoModel.getOrderId());
        if (userId.intValue() != order.getUserId().intValue()) {
            return Message.error("订单有误请重试", null);
        }
        BigDecimal residualRefundPrice = ygReturnOrderService.residualRefundPrice(order.getOrderId());
        BigDecimal subtract = residualRefundPrice.subtract(infoModel.getReturnPrice());
        if (subtract.abs().compareTo(new BigDecimal("1.00")) <= 0) {
            infoModel.setReturnPrice(residualRefundPrice);
        }
        BigDecimal returnAccountPrice = BigDecimal.ZERO;
        BigDecimal refundPrice = BigDecimal.ZERO;
        BigDecimal refundAccountPrice = BigDecimal.ZERO;
        // 退款多于实际付款，优先退实际支付的
        BigDecimal lastPaidPrice = residualRefundPrice.subtract(order.getAccountPrice());
        if (lastPaidPrice.compareTo(BigDecimal.ZERO) < 0) {
            lastPaidPrice = BigDecimal.ZERO;
        }
        if (infoModel.getReturnPrice().compareTo(lastPaidPrice) > 0) {
            returnAccountPrice = infoModel.getReturnPrice().subtract(lastPaidPrice);
        }
        BigDecimal returnPrice = infoModel.getReturnPrice().subtract(returnAccountPrice);

        if (infoModel.getRefundPrice() != null && returnPrice.compareTo(infoModel.getRefundPrice()) >= 0) {
            refundPrice = infoModel.getRefundPrice();
        }
        if (infoModel.getRefundAccountPrice() != null) {
            refundAccountPrice = infoModel.getRefundAccountPrice();
        }
        BigDecimal totalRefundPrice = refundPrice.add(refundAccountPrice);
        if (totalRefundPrice.compareTo(infoModel.getReturnPrice()) > 0) {
            return Message.error("实退总金额大于应退", refundPrice + "+" + refundAccountPrice + "=" + totalRefundPrice);
        }

        YgReturnOrder returnOrder = new YgReturnOrder();
        Long frameCode = ygFrameCodeService.getFrameCode(CodeType.ReOrder, new Date());
        returnOrder.setSupplierId(order.getSupplierId());
        returnOrder.setReturnCode("R" + frameCode);
        returnOrder.setUserId(order.getUserId());
        returnOrder.setOrderId(order.getOrderId());
        returnOrder.setReturnType(ReturnType.Return);
        returnOrder.setReturnPrice(infoModel.getReturnPrice());
        // 退款多于实际付款，优先退实际支付的
        returnOrder.setAccountPrice(returnAccountPrice);
        returnOrder.setProductPrice(returnPrice);
        returnOrder.setRefundPrice(refundPrice);
        returnOrder.setRefundAccountPrice(refundAccountPrice);
        returnOrder.setReturnReasonType(returnReasonType);
        returnOrder.setReturnReason(returnReason);
        returnOrder.setReturnImgPath(imgPaths);
        returnOrder.setStatus(DataStatus.Valid);
        returnOrder.setReturnStatus(ReturnStatus.WaitingReturnMoney);
        returnOrder.setCreateTime(new Date());
        returnOrder.setReturnMode(ReturnMode.OffLine);
        ygReturnOrderService.save(returnOrder);

        BigDecimal lastPrice = returnOrder.getProductPrice();
        BigDecimal lastAccountPrice = returnOrder.getAccountPrice();

        List<YgOrderDetail> orderDetail = order.getOrderDetail();
        Date parse = DateConvertUtils.parse("2019-05-16 10:00:00", DateConvertUtils.DATE_TIME_FORMAT);
        if (order.getCreateTime().after(parse)) {
            saveReturnOrderNew(infoModel, orderDetail, returnOrder.getReturnCode(), returnReasonType, lastPrice, lastAccountPrice);
        } else {
            saveReturnOrderOld(infoModel, orderDetail, returnOrder.getReturnCode(), returnReasonType);
        }
        ygReturnOrderLogService.addReturnOrderLog(returnOrder.getReturnCode(), "线下退货",
                ReturnStatus.WaitingReturnMoney, trueName, "");

        return Message.success(returnOrder.getId());

    }

    public Message saveReturnOrder(YgReturnInfoModel infoModel, ReturnReasonType returnReasonType, String returnReason,
                                   String imgPaths, YgReturnInfoModel returnInfo, Long userId) {
        List<Long> sourceSkuIds = infoModel.getSkuInfos().stream().map(ReturnSkuInfo::getSkuId).collect(Collectors.toList());
        Message checkReturn = ygReturnOrderService.checkReturn(infoModel.getOrderId(), sourceSkuIds, ReturnType.Return);

        if (checkReturn.getType().equals(Message.Type.error)) {
            return checkReturn;
        }
        YgOrder order = ygOrderService.findOrderDetailByOrderId(infoModel.getOrderId());

        if (userId.intValue() != order.getUserId().intValue()) {
            return Message.error("订单有误请重试", null);
        }

        Message message = this.checkManZeng(order, returnInfo);
        if (message.getType().equals(Message.Type.error)) {
            return message;
        }
        YgReturnOrder returnOrder = new YgReturnOrder();
        Long frameCode = ygFrameCodeService.getFrameCode(CodeType.ReOrder, new Date());

        returnOrder.setReturnCode("R" + frameCode);
        returnOrder.setSupplierId(order.getSupplierId());
        returnOrder.setUserId(order.getUserId());
        returnOrder.setOrderId(order.getOrderId());
        returnOrder.setReturnType(ReturnType.Return);
        returnOrder.setReturnPrice(returnInfo.getReturnPrice());
        /*
         * 过滤掉未参与退款的活动单定金
         * */
        ygPrepayBookRecordService.checkBookOrderForReturn(order, returnInfo);
        // 退款多于实际付款，优先退实际支付的
        if (order.getTotalPrice().compareTo(returnInfo.getReturnPrice()) < 0) {
            returnOrder.setAccountPrice(returnInfo.getReturnPrice().subtract(order.getTotalPrice()));
        } else {
            returnOrder.setAccountPrice(new BigDecimal(0));
        }
        returnOrder.setProductPrice(returnInfo.getReturnPrice().subtract(returnOrder.getAccountPrice()));
        returnOrder.setReturnReasonType(returnReasonType);
        returnOrder.setReturnReason(returnReason);
        returnOrder.setReturnImgPath(imgPaths);
        returnOrder.setStatus(DataStatus.Valid);
        returnOrder.setCreateTime(new Date());
        returnOrder.setReturnMode(ReturnMode.OnLine);
        ygReturnOrderService.save(returnOrder);

        BigDecimal lastPrice = returnOrder.getProductPrice();
        BigDecimal lastAccountPrice = returnOrder.getAccountPrice();

        List<YgOrderDetail> orderDetail = order.getOrderDetail();
        Date parse = DateConvertUtils.parse("2019-05-16 10:00:00", DateConvertUtils.DATE_TIME_FORMAT);
        if (order.getCreateTime().after(parse)) {
            saveReturnOrderNew(infoModel, orderDetail, returnOrder.getReturnCode(), returnReasonType, lastPrice, lastAccountPrice);
        } else {
            saveReturnOrderOld(infoModel, orderDetail, returnOrder.getReturnCode(), returnReasonType);
        }

        ygReturnOrderLogService.addReturnOrderLog(returnOrder.getReturnCode(), "您的申请已提交，等待审核", ReturnStatus.WaitingCheck, order.getUserId(), null);

        return Message.success(returnOrder.getReturnCode());
    }

    public void saveReturnOrderOld(YgReturnInfoModel infoModel, List<YgOrderDetail> orderDetail, String returnCode, ReturnReasonType returnReasonType) {
        for (ReturnSkuInfo info : infoModel.getSkuInfos()) {
            for (YgOrderDetail od : orderDetail) {
                if (info.getSkuId().equals(od.getSkuId())) {
                    YgSku sku = ygSkuService.findById(info.getSkuId());
                    YgReturnOrderDetail returnDetail = new YgReturnOrderDetail();
                    returnDetail.setSupplierId(od.getSupplierId());
                    returnDetail.setReturnCode(returnCode);
                    returnDetail.setSkuId(od.getSkuId());
                    returnDetail.setOdId(info.getOrderDetailId());
                    returnDetail.setSkuCode(od.getSkuCode());
                    returnDetail.setSizeName(od.getSize());
                    returnDetail.setPrice(info.getPrice());
                    returnDetail.setProductName(od.getProductName());
                    if (info.getRemark() != null) {
                        returnDetail.setRemark(info.getRemark());
                    }
                    if (ReturnReasonType.ReturnDifference.equals(returnReasonType)) {
                        // 退差价不记录商品数量
                        returnDetail.setAmount(0L);
                    } else {
                        returnDetail.setAmount(info.getQuantity());
                    }
                    returnDetail.setProductId(sku.getProductId());
                    returnDetail.setStatus(DataStatus.Valid);

                    returnDetail.setSourceSkuId(od.getSkuId());
                    returnDetail.setSourceSkuCode(od.getSkuCode());
                    returnDetail.setSourceSizeName(od.getSize());
                    returnDetail.setShortName(od.getShortName());
                    ygReturnOrderDetailService.save(returnDetail);
                }
            }

        }
    }

    public void saveReturnOrderNew(YgReturnInfoModel infoModel, List<YgOrderDetail> orderDetail, String returnCode, ReturnReasonType returnReasonType, BigDecimal lastPrice,
                                   BigDecimal lastAccountPrice) {
        for (OrderDetailReturnData info : infoModel.getReturnDataList()) {
            for (YgOrderDetail od : orderDetail) {
                if (info.getOdId().equals(od.getId())) {
                    YgSku sku = ygSkuService.findById(od.getSkuId());
                    YgReturnOrderDetail returnDetail = new YgReturnOrderDetail();
                    returnDetail.setSupplierId(od.getSupplierId());
                    returnDetail.setReturnCode(returnCode);
                    returnDetail.setSkuId(od.getSkuId());
                    returnDetail.setOdId(info.getOdId());
                    returnDetail.setSkuCode(od.getSkuCode());
                    returnDetail.setSizeName(od.getSize());

                    BigDecimal subtract = info.getThisReturnPrice().subtract(lastPrice);
                    if (subtract.compareTo(BigDecimal.ZERO) > 0) {
                        // 支付余额不足了
                        returnDetail.setPrice(lastPrice);
                        lastPrice = BigDecimal.ZERO;

                        BigDecimal accountSubtract = subtract.subtract(lastAccountPrice);
                        if (accountSubtract.compareTo(BigDecimal.ZERO) > 0) {
                            // 成长基金余额不足
                            returnDetail.setAccountPrice(lastAccountPrice);
                            lastAccountPrice = BigDecimal.ZERO;
                        } else {
                            returnDetail.setAccountPrice(subtract);
                            lastAccountPrice = accountSubtract;
                        }
                    } else {
                        // 支付余额充足
                        returnDetail.setPrice(info.getThisReturnPrice());
                        returnDetail.setAccountPrice(BigDecimal.ZERO);
                        lastPrice = subtract.abs();
                    }
                    returnDetail.setProductName(od.getProductName());

                    if (ReturnReasonType.ReturnDifference.equals(returnReasonType)) {
                        // 退差价不记录商品数量
                        returnDetail.setAmount(0L);
                    } else {
                        returnDetail.setAmount(info.getThisReturnQuantity());
                    }
                    returnDetail.setProductId(sku.getProductId());
                    returnDetail.setStatus(DataStatus.Valid);

                    returnDetail.setSourceSkuId(od.getSkuId());
                    returnDetail.setSourceSkuCode(od.getSkuCode());
                    returnDetail.setSourceSizeName(od.getSize());
                    returnDetail.setShortName(od.getShortName());
                    ygReturnOrderDetailService.save(returnDetail);
                }
            }

        }
    }

    private Message checkManZeng(YgOrder order, YgReturnInfoModel returnInfo) {
        List<YgOrderDetail> skuList = order.getOrderDetail().stream().filter(d -> d.getPromotionType().equals(PromotionType.ManZeng)).collect(Collectors
                .toList());
        if (!CollectionUtils.isEmpty(skuList) && skuList.size() == 1) {
            final YgOrderDetail mz = skuList.get(0);
            BigDecimal mzPrice;
            if (mz.getRemark().startsWith(PromotionType.ManZeng.name())) {
                mzPrice = new BigDecimal(mz.getRemark().split(",")[1]);
            } else {
                mzPrice = new BigDecimal(mz.getRemark());
            }
            BigDecimal subtract = order.getTotalPrice().subtract(returnInfo.getReturnPrice());
            int compareTo = subtract.compareTo(mzPrice);
            if (compareTo < 0) {
                Optional<ReturnSkuInfo> info = returnInfo.getSkuInfos().stream().filter(sku -> sku.getSkuId().equals(mz.getSkuId())).findFirst();
                if (!info.isPresent()) {
                    return Message.error("退货后金额不满足满赠要求", subtract);
                }
            }
        }
        return Message.success("");

    }
}
